home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
presto
/
prest1_0.lha
/
src
/
spinlock.h
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-11
|
4KB
|
206 lines
#ifndef __presto__spinlock_h__
#define __presto__spinlock_h__
//
// Spinlocks should be used when the caller expects to need to touch
// a piece of data for only a very short time. Interference on that
// data will cause the later thread to spin (his processor does not
// become available!)
//
// USE WITH CAUTION
//
// Modification History:
//
// 28-Dec-1989 JEF
// Add class HC_Spinlock (for sequent symmetry only). This variation of
// a spinlock works well when there is high contention for the lock.
// After original by raj.
//
//
// If compiling presto kernel, or compiling with preemption
// included, then include code to make threads not preemptable
// inside spinlock. Else, omit for speed.
//
//
// For better locking performance, spinlocks should be compiled inline.
//
#define DO_SPINLOCK_INLINE
#ifdef DO_SPINLOCK_INLINE
#define SPINLOCK_INLINE inline
#else
#define SPINLOCK_INLINE
#endif
#ifdef sequent
#include "parallel.h"
extern "C" {
void S_INIT_LOCK (slock_t *);
void S_LOCK (slock_t *);
void S_UNLOCK (slock_t *);
int S_CLOCK (slock_t *);
void HC_S_LOCK(hc_slock_t *);
void HC_S_UNLOCK(hc_slock_t *);
int HC_S_INIT_LOCK(hc_slock_t *); // should probably be void
int HC_S_CLOCK(hc_slock_t *);
int HC_S_IS_LOCKED(hc_slock_t *);
}
#endif /* sequent */
#ifdef sun
#include "parallel.h"
#define S_LOCK s_lock
#endif /* sun */
#ifdef vax
typedef int slock_t;
#define L_UNLOCKED 0
#define S_LOCK s_lock
#define S_UNLOCK s_unlock
#define S_INIT_LOCK s_init_lock
#define S_CLOCK s_clock
#endif /* vax */
#ifdef mips
typedef int slock_t;
#define L_UNLOCKED 0
#define S_LOCK s_lock
#define S_UNLOCK s_unlock
#define S_INIT_LOCK s_init_lock
#define S_CLOCK s_clock
#endif /* mips */
extern void s_init_lock (slock_t*);
extern void s_lock (slock_t*);
extern void s_unlock (slock_t*);
extern int s_clock (slock_t*);
class Thread;
class Spinlock : public Object {
slock_t sl_lock;
#ifdef PROFILE
int sl_q;
#endif
public:
Spinlock(char *name = 0)
{
S_INIT_LOCK(&sl_lock);
name = name; // satisfy cfront and/or ANSI C
#ifdef PROFILE
sl_q = SLInit(name);
#endif
}
SPINLOCK_INLINE ~Spinlock();
//
// Acquire lock, spinning until it is free.
//
SPINLOCK_INLINE void lock();
//
// Acquire lock and return true iff lock is free, else return
// false immediately without spinning.
//
int trylock()
{ return S_CLOCK(&sl_lock); }
//
// Old name for trylock().
//
int checklock()
{ return trylock(); }
//
// Return true iff locked, else false.
//
int testlock()
{ return sl_lock; }
//
// Release lock.
//
SPINLOCK_INLINE void unlock();
virtual void print(ostream& = cout);
};
//
// High-contention spinlocks are only implemented on sequent symmetry.
//
#ifdef sequent
#ifdef i386
class Thread;
class HC_Spinlock : public Object {
hc_slock_t sl_lock;
#ifdef PROFILE
int sl_q;
#endif
public:
HC_Spinlock(char *name = 0)
{
HC_S_INIT_LOCK(&sl_lock);
name = name; // satisfy cfront and/or ANSI C
#ifdef PROFILE
sl_q = SLInit(name);
#endif
}
~HC_Spinlock()
{
//
// We should abort if the lock is not free. (?) XXX
// For now just unlock it for backward compatibility.
//
if (testlock())
unlock();
#ifdef PROFILE
SLDispose(sl_q);
#endif
}
//
// Acquire lock, spinning until it is free.
//
inline void lock();
//
// Acquire lock and return true iff lock is free, else return
// false immediately without spinning.
//
int trylock() {
cerr << "HC_Spinlock::trylock(): unimplemented\n";
/* XXX for now, always returns FALSE */
return (HC_S_CLOCK(&sl_lock));
}
//
// Old name for trylock().
//
int checklock()
{ return (trylock()); }
//
// Return true iff locked, else false.
//
int testlock()
{ return HC_S_IS_LOCKED(&sl_lock); }
//
// Release lock.
//
inline void unlock();
virtual void print(ostream& = cout);
};
#endif /* i386 */
#endif /* sequent */
#endif /* __presto__spinlock_h__ */